// Package main 提供了一个使用 Gin 框架处理各种请求参数的 Web 服务器示例
package main

import (
	"bytes"
	"fmt"
	"io"

	"github.com/gin-gonic/gin" // 导入 Gin Web 框架
)

// main 函数是程序入口点，初始化 Gin 路由器并启动 Web 服务器
func main() {
	// 创建默认的 Gin 路由器实例
	r := gin.Default()

	// 注册路由：GET 请求 "/" 路径处理查询参数
	// 示例: ?name=123&age=30
	r.GET("/", func(c *gin.Context) {
		// 获取查询参数 name 的值
		// 如果参数不存在，返回空字符串
		name := c.Query("name")

		// 获取查询参数 age 的值，如果参数不存在则返回默认值 "30"
		age := c.DefaultQuery("age", "30")

		// 打印获取到的参数值到控制台
		println(name, age)

		byteData, _ := io.ReadAll(c.Request.Body)
		fmt.Println(string(byteData))
		// 读了之后，body就没了，阅后即焚
		c.Request.Body = io.NopCloser(bytes.NewReader(byteData))
	})

	// 注册路由：GET 请求 "/user/:id" 路径处理路径参数
	// 示例: /user/2
	r.GET("user/:id", func(c *gin.Context) {
		// 获取路径参数 id 的值
		uid := c.Param("id")

		// 打印获取到的参数值到控制台
		println(uid)
	})

	// 注册路由：POST 请求 "/form" 路径处理表单数据
	r.POST("form", func(c *gin.Context) {
		// 获取表单参数 name 的值
		name := c.PostForm("name")

		// 获取表单参数 age 的值和是否存在标识
		age, ok := c.GetPostForm("age")

		// 打印获取到的参数值和是否存在标识到控制台
		println(name, age, ok)
	})

	// 注册路由：POST 请求 "/file" 路径处理单文件上传
	r.POST("file", func(c *gin.Context) {
		// 获取上传的文件信息
		fileHeader, err := c.FormFile("file")
		if err != nil {
			// 如果获取文件失败，打印错误信息并返回
			println(err)
			return
		}

		// 打印文件名和文件大小到控制台
		println(fileHeader.Filename)
		println(fileHeader.Size)

		// 方案1: 读取文件内容并保存
		// file, _ := fileHeader.Open()
		// byteData, _ := io.ReadAll(file)
		// err = os.WriteFile("test.png", byteData, 0666)
		// println(err)

		// 方案2: 直接保存上传的文件
		// 参数1: 上传的文件信息
		// 参数2: 保存的文件路径和文件名
		err = c.SaveUploadedFile(fileHeader, "uploads/"+fileHeader.Filename)
		println(err)
	})

	// 注册路由：POST 请求 "/mult" 路径处理多文件上传
	r.POST("mult", func(c *gin.Context) {
		// 获取多部分表单数据
		form, err := c.MultipartForm()
		if err != nil {
			// 如果获取表单数据失败，打印错误信息并返回
			println(err)
			return
		}

		// 遍历表单中的所有文件
		for _, headers := range form.File {
			// 遍历每个文件头信息
			for _, v := range headers {
				// 保存上传的文件
				// 参数1: 文件头信息
				// 参数2: 保存的文件路径和文件名
				c.SaveUploadedFile(v, "uploads/"+v.Filename)
			}
			// println(k, v)
		}

	})

	// 启动 HTTP 服务器，监听 8000 端口
	// 如果启动失败，会返回一个 error 类型的错误信息
	if err := r.Run(":8000"); err != nil {
		// 使用 panic 输出启动失败的错误信息
		panic(err)
	}
}
